home *** CD-ROM | disk | FTP | other *** search
/ Gold Medal Software 3 / Gold Medal Software - Volume 3 (Gold Medal) (1994).iso / utils2 / mymous12.arj / KNOBS.ASM < prev    next >
Assembly Source File  |  1994-02-12  |  9KB  |  337 lines

  1. ; KNOBS
  2. ; Andrew Forrest
  3. ; Started 6 January 1994
  4. ; $VER: Knobs.asm 1.0 (12.02.94)
  5.  
  6. ; Assembled with DEVPAC 3.02
  7.     nolist
  8.  
  9. ; Starting from V36, the Amiga OS has several bit switches embedded in
  10. ; various control structures. Several programs allow the user to alter these
  11. ; settings, including my mouse-accelerator/swiss-army-knife program MyMouse.
  12. ; I didn't like having all of these switch options in MyMouse, especially
  13. ; since there were several other switches I could think of adding, so I have
  14. ; split these extra options off into a seperate program--KNOBS!
  15.  
  16.     include    everything.i
  17.     
  18. Execbase    equ    4
  19.  
  20.     ;*╗╗  Code entrypoint
  21.     ;*╗╗  Allocate global memory for variables
  22. MAIN:    move.l    Execbase,a6
  23.     moveq    #Globals_SIZEOF,d0
  24.     move.l    #MEMF_CLEAR,d1
  25.     just    AllocMem
  26.     tst.l    d0
  27.       beq      Unhappy
  28.     move.l    d0,a5
  29.     move.l    a6,execbase(a5) ; Cache local (fast?) copy of execbase
  30.     
  31.     ;*╗╗  Open the DOS library
  32.     lea    dosname(pc),a1
  33.     moveq    #0,d0    ; Open any version
  34.     just    OpenLibrary
  35.     move.l    d0,dosbase(a5)
  36.       beq      Unhappy
  37.  
  38.     ;*╗╗  Open the utility library
  39.     moveq    #msg_NoUtility,d7
  40.     lea    utilityname(pc),a1
  41.     moveq    #37,d0
  42.     just    OpenLibrary
  43.     move.l    d0,utilitybase(a5)
  44.       beq      Error
  45.     
  46.     moveq    #msg_OldDos,d7
  47.     move.l    dosbase(a5),a6
  48.     cmp.w    #36,LIB_VERSION(a6)    ; Need at least V36 DOS for
  49.       blo      Error        ; command-line parsing
  50.     lea    Template(pc),a0
  51.     move.l    a0,d1
  52.     lea    Options(a5),a0
  53.     move.l    a0,d2
  54.     moveq    #0,d3
  55.     moveq    #msg_NoArgs,d7
  56.     just    ReadArgs
  57.     move.l    d0,RdArgs(a5)
  58.       beq      Error
  59.     
  60.     ;*╗╗  Handle 'STAR' option.
  61.     move.l    WildStarOption(a5),d1
  62.     beq.s    .NoStar
  63.       move.l      dosbase(a5),a0
  64.       move.l      dl_Root(a0),a0    ; (a6==dosbase(a5))
  65.       lea      rn_Flags(a0),a0
  66.       moveq      #0,d0
  67.       move.l      d1,a1
  68.       bsr      StringBit
  69. .NoStar
  70.  
  71.     ;*╗╗  Perform NoClick, if desired.
  72.     ;  (d2=charflag;d3=unit#;d4=^MsgPort;a2=argument;a3=^IORequest)
  73.     move.l    execbase(a5),a6
  74.     move.l    NoClickOption(a5),d0
  75.       beq      .NoNoClick
  76.     move.l    d0,a2
  77.     ;*╗╗  Create an IORequest structure
  78.     just    CreateMsgPort
  79.     move.l    d0,d4    ; MsgPort in d4
  80.       beq      .NoNoClick
  81.     move.l    d4,a0
  82.     moveq    #IOSTD_SIZE,d0
  83.     just    CreateIORequest
  84.     tst.l    d0
  85.       beq.s      .fail
  86.     move.l    d0,a3    ; IORequest in a3
  87.     moveq    #-1,d3
  88. .ClickLoop    addq.l    #1,d3    ; Count trackdisk units
  89.     move.b    (a2)+,d2    ; Get next character of flag string
  90.     beq.s    .endloop    ; Quit on string null-terminator
  91.       lea      TrackName(pc),a0    ;device name
  92.       move.l      d3,d0    ;unit number
  93.       lea      (a3),a1    ;IO request
  94.       moveq.l      #0,d1    ;flags
  95.       just      OpenDevice
  96.       tst.l      d0
  97.     bne.s    .ClickLoop
  98.       move.l      IO_UNIT(a3),a0
  99.       lea      TDU_PUBFLAGS(a0),a0
  100.       moveq      #TDPB_NOCLICK,d0
  101.       move.b      d2,d1
  102.       bsr      CharBit
  103.       lea      (a3),a1
  104.       just      CloseDevice
  105.     bra.s    .ClickLoop
  106. .endloop    lea    (a3),a0
  107.     just    DeleteIORequest
  108. .fail    move.l    d4,a0
  109.     just    DeleteMsgPort
  110. .NoNoClick
  111.  
  112.     ;*╗╗  Border-blanking option.
  113.     tst.l    BorderBlankOption(a5)
  114.     beq.s    .NoBBlank
  115.       moveq      #msg_BBlankGfx,d7
  116.       lea      gfxname(pc),a1
  117.       moveq      #39,d0
  118.       syscall      OpenLibrary
  119.       move.l      d0,graphicsbase(a5)
  120.         beq        Error
  121.       move.l      d0,a0
  122.       lea      gb_BP3Bits(a0),a0
  123.       moveq      #5,d0
  124.       move.l      BorderBlankOption(a5),a1
  125.       bsr      StringBit
  126.       moveq      #msg_BBlankInt,d7
  127.       lea      intname(pc),a1
  128.       moveq      #33,d0
  129.       just      OpenLibrary
  130.       move.l      d0,intuitionbase(a5)
  131.         beq.s        Error
  132.       intcall      RemakeDisplay
  133. .NoBBlank
  134.  
  135.     ;*╗╗  Alert-timer option.
  136.     move.l    AlertTimerOption(a5),d0
  137.     beq.s    .NoAlertTimer
  138.       moveq      #msg_ATiOldExec,d7
  139.       move.l      d0,a0
  140.       move.l      (a0),d0
  141.       move.l      execbase(a5),a0
  142.       cmp.w      #39,LIB_VERSION(a0)
  143.         blo.s        Error
  144.       move.l      d0,LastAlert+3*4(a0)
  145. .NoAlertTimer
  146.  
  147. Satisfied:    moveq    #RETURN_OK,d0    ; Assume a happy ending
  148.     bra.s    Deallocate
  149. Unhappy:    moveq    #RETURN_FAIL,d0    ; Or maybe not
  150.  
  151. ; Jump to this routine with d0=Returncode
  152. Deallocate:    push.l    d0
  153.     move.l    a5,d0
  154.     beq.s    .nothing    ; Global structure not even there
  155.       tst.l      dosbase(a5)
  156.       beq.s      .no_dos    ; Got to check, since we're _calling_ dos
  157.         move.l        RdArgs(a5),d1
  158.         doscall        FreeArgs    ; Does nothing if passed NULL
  159. .no_dos      lea      LibraryBases(a5),a2
  160.       move.l      execbase(a5),a6
  161.       moveq      #NumLibraries-1,d2
  162. .librryloop        move.l        (a2)+,a1
  163.         just        CloseLibrary    ; Does nothing if passed NULL
  164.       dbra      d2,.librryloop
  165.       lea      (a5),a1
  166.       moveq      #Globals_SIZEOF,d0
  167.       just      FreeMem
  168. .nothing    pop.l    d0    ; Get RETURN_ code back and...
  169.     rts    ; Return to DOS
  170.  
  171. ;***************************************************************************
  172. ;**  Error conditions
  173.  
  174. ; Branch to here on error condition with d7=errn
  175. Error:    move.w    ErrorTable(pc,d7.w),d7
  176.     lea    ErrorTable(pc,d7.w),a0
  177.     bsr    Message
  178.     bra    Unhappy
  179.  
  180. errn    set    0
  181. Err    macro    ; Message-tag
  182.       dc.w      _\1-ErrorTable    ;The error-message-table-entry
  183. msg_\1      equ      errn    ; The identifier (offset) for that entry
  184. errn      set      errn+2    ; Next table offset
  185.     endm
  186.  
  187. ErrorTable:    Err    OldDos
  188.     Err    NoUtility
  189.     Err    NoArgs
  190.     Err    BBlankGfx
  191.     Err    BBlankInt
  192.     Err    ATiOldExec
  193.  
  194. _OldDos    dc.b    "You need Release 2 of AmigaDOS to use this program.",0
  195. _NoUtility    dc.b    "Can't open utility.library V37.",0
  196. _NoArgs    dc.b    "Unable to read command-line arguments.",0
  197. _BBlankGfx    dc.b    "Can't open graphics.library V39 for the BORDERBLANK option.",0
  198. _BBlankInt    dc.b    "Can't open intuition.library for the BORDERBLANK option.",0
  199. _ATiOldExec    dc.b    "You need Release 3 to use the ALERTTIMER option.",0
  200.  
  201.     even
  202. ;***************************************************************************
  203. ;***************************************************************************
  204. ;**  Useful routines
  205.  
  206. ; Print out the name of the program, colon, null-term string and end-of-line.
  207. ; Takes a0=^string\0; a5=^Globals (with dosbase); Returns, Trashes nil;
  208. Message:
  209.     pushm.l    a0-a2/a6/d0-d4
  210.     lea    (a0),a2    ; Store stringpointer for safe-keeping
  211.     doscall    Output    ; \ Get the output channel
  212.     move.l    d0,d4    ; / And store in d4
  213.     move.l    d4,d1
  214.     lea    ProgramName(pc),a0
  215.     move.l    a0,d2
  216.     moveq    #NameLength,d3
  217.     just    Write    ; Write the header: "KNOBS: "
  218.     move.l    d4,d1
  219.     move.l    a2,d2
  220.     moveq    #-1,d3    ; Assume string of zero length
  221. .loop      addq.l      #1,d3    ; ...add one to length
  222.       tst.b      (a2)+    ; ...test for null
  223.     bne.s    .loop    ; ...and exit loop when we get it
  224.     just    Write    ; Write out this string
  225.     move.l    d4,d1
  226.     lea    CarriageReturn(pc),a0
  227.     move.l    a0,d2
  228.     moveq    #1,d3
  229.     just    Write    ; Write out the Carriage-Return
  230.     popm.l    a0-a2/a6/d0-d4
  231.     rts
  232. ProgramName:    dc.b    "KNOBS: "
  233. NameLength    equ    *-ProgramName
  234. CarriageReturn:    dc.b    10
  235.  
  236. ; Uses Bit to change a bit based on a string which contains "ON", "OFF" or 
  237. ; "CHANGE"--any other string has no effect. Uses utility library to do a 
  238. ; case-insensitive string comparison.
  239. ; Takes a0=^flags; d0=bit#; a1=^string; Returns, Trashes nothing.
  240. ; Uses a2=^search string; d2=loopcounter=[CHANGE,OFF,ON]; d3=str offset;
  241. StringBit:    push.w    d1
  242.     pushm.l    a0-a3/a6/d0/d2-d3
  243.     move.l    utilitybase(a5),a6
  244.     lea    (a1),a2    ; Store user string for safekeeping
  245.     moveq    #0,d3    ; Clear top of d3
  246.     moveq    #3,d2    ; Initialise loopcounter==codenumber
  247. .loop      lea      (a2),a0    ;   String supplied by user
  248.       move.b      Table-1(pc,d2.w),d3    ;   Look up offset from table
  249.       lea      Table(pc,d3.w),a1    ;   Obtain string from offset
  250.       just      Stricmp    ;   Compare the two strings
  251.       tst.l      d0
  252.     dbeq    d2,.loop    ; Loop until match or counter reaches -1
  253. .endloop    move.b    d2,d1
  254.     popm.l    a0-a3/a6/d0/d2-d3
  255.     bsr.s    Bit
  256.     pop.w    d1
  257.     rts
  258. Table:    dc.b    On-Table,Off-Table,Change-Table
  259. On    dc.b    "ON",0
  260. Off    dc.b    "OFF",0
  261. Change    dc.b    "CHANGE",0
  262.     even
  263.  
  264. ; Changes a bit based on a single character, d1, which is `1' (SET), `0'
  265. ; (CLEAR), `*' (CHANGE) or `-' (IGNORE).
  266. ; Takes a0=^flags; d0=bit#; d1.b=character; Trashes, returns nothing.
  267. CharBit:    pushm.l    a1/d2
  268.     lea    CharTable(pc),a1
  269.     moveq    #3,d2
  270. .loop      cmp.b      (a1)+,d1
  271.     dbeq    d2,.loop    ; Keep looping til char=d1 or count=-1
  272. .endloop    move.b    d2,d1
  273.     bsr.s    Bit
  274.     popm.l    a1/d2
  275.     rts
  276. CharTable:    dc.b    "*01-"
  277.  
  278. ; (Possibly) changes a bit in a memory location based on whether d1
  279. ; is BITSET=1, BITCLEAR=2, BITCHANGE=3 or BITIGNORE=anything else.
  280. ; Takes a0=^flags; d0=bit#; d1.b=action; Returns & trashes nothing.
  281. Bit:    push.w    d1
  282.     subq.b    #1,d1
  283.     bne.s    .noset    ; IF d1==BITSET THEN
  284. .set     bset     d0,(a0)    ;   set
  285.     bra.s    .end    ; ELSE
  286. .noset     subq.b     #1,d1
  287.      bne.s     .noclear    ;   IF d1==BITCLEAR THEN
  288. .clear      bclr      d0,(a0)    ;      clear
  289.      bra.s     .end    ;   ELSE
  290. .noclear      subq.b      #1,d1
  291.       bne.s      .end    ;      IF d1==BITCHANGE THEN
  292. .change       bchg       d0,(a0)    ;         change
  293. .end    pop.w    d1    ; ENDIF
  294.     rts
  295.  
  296.  
  297. ;***************************************************************************
  298. ;**  Static data
  299.     dc.b    "$VER: Knobs 1.0 (06.02.94)"
  300.  
  301. dosname    dc.b    "dos.library",0
  302. gfxname    dc.b    "graphics.library",0
  303. intname    dc.b    "intuition.library",0
  304. utilityname    dc.b    "utility.library",0
  305.  
  306. TrackName:    dc.b    "trackdisk.device",0
  307.  
  308. ;***************************************************************************
  309.  
  310. ; Structure of global data area
  311.     STRUCTURE    Globals,0
  312.  
  313.     APTR    execbase
  314.     LABEL    LibraryBases
  315.     APTR    dosbase
  316.     APTR    graphicsbase
  317.     APTR    intuitionbase
  318.     APTR    utilitybase
  319.     LABEL    EndLibs
  320. NumLibraries    equ    (EndLibs-LibraryBases)/4
  321.  
  322.     APTR    RdArgs
  323.  
  324.     LABEL    Options
  325.     LONG    AlertTimerOption
  326.     LONG    BorderBlankOption
  327.     LONG    NoClickOption
  328.     LONG    WildStarOption
  329.     LABEL    Globals_SIZEOF
  330.  
  331. Template:    dc.b    "ALERTTIMER/K/N,"
  332.     dc.b    "BBLANK=BORDERBLANK/K,"
  333.     dc.b    "NOCLICK=NODISKCLICK/K,"
  334.     dc.b    "STAR=WILDSTAR/K"
  335.     dc.b    0
  336.  
  337.